package com.ruoyi.system.service.impl;

import java.util.*;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.constant.IotConstants;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.system.cache.AlarmConfigCache;
import com.ruoyi.system.domain.Forest.IotDeviceInfo;
import com.ruoyi.system.domain.Forest.second.DeviceDataResult;
import com.ruoyi.system.domain.SysAlarmConfig;
import com.ruoyi.system.domain.SysBuilding;
import com.ruoyi.system.domain.SysDevice;
import org.nutz.el.El;
import org.nutz.lang.Lang;
import org.nutz.lang.util.Context;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.system.mapper.SysAlarmMapper;
import com.ruoyi.system.domain.SysAlarm;
import com.ruoyi.system.service.ISysAlarmService;

/**
 * 告警Service业务层处理
 * 
 * @author ruoyi
 * @date 2024-08-13
 */
@Service
public class SysAlarmServiceImpl implements ISysAlarmService 
{
    @Autowired
    private AlarmConfigCache alarmConfigCache;

    @Autowired
    private SysAlarmMapper sysAlarmMapper;

    /**
     * 查询告警
     * 
     * @param alarmId 告警主键
     * @return 告警
     */
    @Override
    public SysAlarm selectSysAlarmByAlarmId(Long alarmId)
    {
        return sysAlarmMapper.selectSysAlarmByAlarmId(alarmId);
    }

    /**
     * 查询告警列表
     * 
     * @param sysAlarm 告警
     * @return 告警
     */
    @Override
    public List<SysAlarm> selectSysAlarmList(SysAlarm sysAlarm)
    {
        return sysAlarmMapper.selectSysAlarmList(sysAlarm);
    }

    /**
     * 新增告警
     * 
     * @param sysAlarm 告警
     * @return 结果
     */
    @Override
    public int insertSysAlarm(SysAlarm sysAlarm)
    {
        sysAlarm.setCreateTime(DateUtils.getNowDate());
        return sysAlarmMapper.insertSysAlarm(sysAlarm);
    }


    /**
     * 触发Iot设备报警
     * @return
     */
    @Override
    public int insertSecondDeviceIotAlarm(DeviceDataResult iotDeviceInfo, SysDevice device){
        SysAlarm sysAlarm = new SysAlarm();
        SysAlarmConfig alarmConfig = alarmConfigCache.getAlarmConfig(device.getAlarmConfigId());
        sysAlarm.setAlarmConfigId(device.getAlarmConfigId());
        sysAlarm.setAlarmLevel(alarmConfig.getAlarmLevel());
        sysAlarm.setAlarmType(IotConstants.ALARM_TYPE_2);
        sysAlarm.setAlarmContent(alarmConfig.getAlarmContent());
        sysAlarm.setResultContent(JSON.parseObject(JSON.toJSONString(iotDeviceInfo)));
        List<Map<String, Object>> matchList = new ArrayList<>();
        Context context = Lang.context();
        context.set("iot", iotDeviceInfo);

        List <String> alarmField = Arrays.asList(alarmConfig.getInjectionField().split(","));
        //用&& 分隔 转换为数组
        for (String match :alarmConfig.getAlarmExpression().split("&&")){
            if ((boolean)(El.eval(context, match))){
                Map<String, Object> map = new HashMap<>();
                //匹配公式
                map.put("match", match);
                for (String field : alarmField){
                    if (match.startsWith(field)){
                        //报警字段
                        map.put("field", field);
                        //报警值
                        map.put("value", El.eval(context, field));
                        break;
                    }
                }
                matchList.add(map);
            }
        }
        sysAlarm.setMatchFiled(JSON.parseArray(JSON.toJSONString(matchList)));
        return saveAlarm(device, sysAlarm);
    }
    /**
     * 触发Iot设备报警
     * @return
     */
    @Override
    public int insertDeviceIotAlarm(IotDeviceInfo iotDeviceInfo,SysDevice device){
        SysAlarm sysAlarm = new SysAlarm();
        SysAlarmConfig alarmConfig = alarmConfigCache.getAlarmConfig(device.getAlarmConfigId());
        sysAlarm.setAlarmConfigId(device.getAlarmConfigId());
        sysAlarm.setAlarmLevel(alarmConfig.getAlarmLevel());
        sysAlarm.setAlarmType(IotConstants.ALARM_TYPE_2);
        sysAlarm.setAlarmContent(alarmConfig.getAlarmContent());
        sysAlarm.setResultContent(JSON.parseObject(JSON.toJSONString(iotDeviceInfo)));
        List<Map<String, Object>> matchList = new ArrayList<>();
        Context context = Lang.context();
        context.set("iot", iotDeviceInfo);

        List <String> alarmField = Arrays.asList(alarmConfig.getInjectionField().split(","));
        //用&& 分隔 转换为数组
        for (String match :alarmConfig.getAlarmExpression().split("&&")){
            if ((boolean)(El.eval(context, match))){
                Map<String, Object> map = new HashMap<>();
                //匹配公式
                map.put("match", match);
                for (String field : alarmField){
                    if (match.startsWith(field)){
                        //报警字段
                        map.put("field", field);
                        //报警值
                        map.put("value", El.eval(context, field));
                        break;
                    }
                }
                matchList.add(map);
            }
        }
        sysAlarm.setMatchFiled(JSON.parseArray(JSON.toJSONString(matchList)));
        return saveAlarm(device, sysAlarm);
    }
    /**
     * 设备报警
     * @return
     */
    @Override
    public int insertDeviceAlarm(SysDevice device){
        SysAlarm sysAlarm = new SysAlarm();
        sysAlarm.setAlarmConfigId(0L);
        sysAlarm.setAlarmLevel(IotConstants.ALARM_LEVEL_1);
        sysAlarm.setAlarmType(IotConstants.ALARM_TYPE_3);
        sysAlarm.setAlarmContent(device.getDeviceCode()+"读取数据异常");
        return saveAlarm(device, sysAlarm);
    }

    /**
     * 关闭阀门，触发热量增加报警
     * @param device
     * @return
     */
    @Override
    public int insertCloseAlarm(SysDevice device){
        SysAlarm sysAlarm = new SysAlarm();
        sysAlarm.setAlarmConfigId(0L);
        sysAlarm.setAlarmLevel(IotConstants.ALARM_LEVEL_1);
        sysAlarm.setAlarmType(IotConstants.ALARM_TYPE_4);
        sysAlarm.setAlarmContent(device.getDeviceId()+"增加了热量,请注意关注");
        return saveAlarm(device, sysAlarm);
    }

    private int saveAlarm(SysDevice device, SysAlarm sysAlarm, String suggestContent){
        sysAlarm.setAlarmStatus(IotConstants.ALARM_STATUS_UNHANDLED);
        sysAlarm.setCreateTime(DateUtils.getNowDate());
        sysAlarm.setDeviceId(device.getDeviceId());
        sysAlarm.setDeptId(device.getDeptId());
        //获取最近一次告警
        SysAlarm lastAlarm = sysAlarmMapper.selectLastAlarm(device.getDeviceId(),sysAlarm.getAlarmType());
        if (lastAlarm == null) {
            sysAlarm.setLastAlarmTime(DateUtils.getNowDate());
        }else {
            //最近一次未处理，则使用最近一次告警时间
            if (lastAlarm.getAlarmStatus().equals(IotConstants.ALARM_STATUS_UNHANDLED)) {
                sysAlarm.setLastAlarmTime(lastAlarm.getLastAlarmTime());
            } else { //最近一次已处理，则使用当前时间
                sysAlarm.setLastAlarmTime(DateUtils.getNowDate());
            }
        }
        return sysAlarmMapper.insertSysAlarm(sysAlarm);
    }
    /**
     * 修改告警
     * 
     * @param sysAlarm 告警
     * @return 结果
     */
    @Override
    public int updateSysAlarm(SysAlarm sysAlarm)
    {
        sysAlarm.setUpdateTime(DateUtils.getNowDate());
        return sysAlarmMapper.updateSysAlarm(sysAlarm);
    }

    /**
     * 批量删除告警
     * 
     * @param alarmIds 需要删除的告警主键
     * @return 结果
     */
    @Override
    public int deleteSysAlarmByAlarmIds(Long[] alarmIds)
    {
        return sysAlarmMapper.deleteSysAlarmByAlarmIds(alarmIds);
    }

    /**
     * 删除告警信息
     * 
     * @param alarmId 告警主键
     * @return 结果
     */
    @Override
    public int deleteSysAlarmByAlarmId(Long alarmId)
    {
        return sysAlarmMapper.deleteSysAlarmByAlarmId(alarmId);
    }
}
